#include "StdAfx.h"
#include "World.h"


CWorld::CWorld(void)
{
	InitWorld();
}


CWorld::~CWorld(void)
{
}

void CWorld::InitWorld()
{
	// Init world map
	for (unsigned short i = 0; i < WORLD_WIDTH; ++i)
	{
		for (unsigned short j = 0; j < WORLD_HEIGHT; ++j)
		{
			m_world[i][j] = EMPTY_CELL;
		}
	}

	// Init units map
	
	for (unsigned short i = 0; i < WORLD_WIDTH; ++i)
	{
		for (unsigned short j = 0; j < WORLD_HEIGHT; ++j)
		{
			m_unitsMap[i][j] = -1;
		}
	}

	// Init world state
	m_worldState = DAY;
	m_currDwarfId = -1;
}

int CWorld::GetWorldCell(int x, int y)const
{
	if ((x >= 0 && x < WORLD_WIDTH) && (y >= 0 && y < WORLD_HEIGHT))
	{
		return m_world[x][y];
	}
	return -1;
}

worldState CWorld::GetWorldState()const
{
	return m_worldState;
}

std::string CWorld::GetWorldString()const
{
	std::string worldString;
		
	for (unsigned short j = 0; j < WORLD_HEIGHT; ++j)
	{		
		for (unsigned short i = 0; i < WORLD_WIDTH; ++i)
		{
			if (m_unitsMap[i][j] == -1)
			{
				worldString.push_back(m_world[i][j]);
			}
			else if (m_unitsMap[i][j] == m_currDwarfId)
			{
				worldString.push_back(CURRENT_DWARF_CELL);
			}
			else
			{
				worldString.push_back(DWARF_CELL);
			}
		}
		worldString.push_back('\n');
	}

	return worldString;
}

std::string CWorld::GetWorldStateString()const
{
	std::string worldStateString;

	switch (m_worldState)
	{
	case DAY:
		worldStateString = "Day";
		break;
	case NIGHT:
		worldStateString = "Night";
		break;
	}

	return worldStateString;
}

bool CWorld::CreateDwarf(int x, int y)
{
	if ((x >= 0 && x < WORLD_WIDTH) && (y >= 0 && y < WORLD_HEIGHT))
	{
		if (m_unitsMap[x][y] == -1)
		{
			// Creating new dwarf
			m_dwarfes.push_back(CDwarf(x, y));
			m_unitsMap[x][y] = m_dwarfes.size() - 1;
			return true;
		}
	}
	return false;
}

bool CWorld::SelectDwarf(int dwarfId)
{
	if (dwarfId >= 0 && dwarfId < m_dwarfes.size())
	{
		m_currDwarfId = dwarfId;
		return true;
	}
	return false;
}

bool CWorld::SelectDwarf(int x, int y)
{	
	if ((x >= 0 && x < WORLD_WIDTH) && (y >= 0 && y < WORLD_HEIGHT))
	{
		if (m_unitsMap[x][y] != -1)
		{
			m_currDwarfId = m_unitsMap[x][y];
			return true;
		}
	}
	return false;
}

bool CWorld::MoveCurrentDwarf(moveDirection direction)
{
	if (m_currDwarfId != -1)
	{
		int currX = m_dwarfes[m_currDwarfId].GetX();
		int currY = m_dwarfes[m_currDwarfId].GetY();

		switch (direction)
		{
		case UP:
			{
				if (CheckForEmptyPlace(currX, currY - 1))
				{
					TranslateCurrentDwarf(currX, currY - 1);
					return true;
				}
			}
			break;
		case RIGHT:
			{
				if (CheckForEmptyPlace(currX + 1, currY))
				{
					TranslateCurrentDwarf(currX + 1, currY);
					return true;
				}
			}
			break;
		case DOWN:
			{				
				if (CheckForEmptyPlace(currX, currY + 1))
				{
					TranslateCurrentDwarf(currX, currY + 1);
					return true;
				}
			}
			break;
		case LEFT:
			{
				if (CheckForEmptyPlace(currX - 1, currY))
				{
					TranslateCurrentDwarf(currX - 1, currY);
					return true;
				}
			}
			break;
		}
	}
	return false;
}

bool CWorld::CheckForEmptyPlace(int x, int y)
{
	if ((x >= 0 && x < WORLD_WIDTH) && (y >= 0 && y < WORLD_HEIGHT))
	{
		return (m_unitsMap[x][y] == -1);
	}
	return false;
}

void CWorld::TranslateCurrentDwarf(int x, int y)
{
	int currX = m_dwarfes[m_currDwarfId].GetX();
	int currY = m_dwarfes[m_currDwarfId].GetY();
	
	m_dwarfes[m_currDwarfId].SetX(x);
	m_dwarfes[m_currDwarfId].SetY(y);

	m_unitsMap[currX][currY] = -1;
	m_unitsMap[x][y] = m_currDwarfId;
}

int CWorld::GetSelectedDwarfId()const
{
	return m_currDwarfId;
}